﻿
namespace System.Linq.Reactive
{
    /// <summary>Простейший наблюдатель</summary>
    /// <typeparam name="T">Объект события</typeparam>
    public class SimpleObserverEx<T> : IObserverEx<T>
    {
        /// <summary>События появления следующего объекта в последовательности</summary>
        public event Action<T> Next;

        /// <summary>Событие завершения последовательности</summary>
        public event Action Complited;

        /// <summary>Событие сброса последовательности</summary>
        public event Action Reset;

        /// <summary>Событие появления исключения</summary>
        public event Action<Exception> Exception;

        /// <summary>Тэг наблюдателя</summary>
        public object Tag { get; set; }

        /// <summary>Метод генерации события появления следующего объекта</summary>
        /// <param name="item">Следующий объект в последовательности</param>
        public virtual void OnNext(T item) { var next = Next; if(next != null) next(item); }

        /// <summary>Метод генерации события завершения последовательности</summary>
        public virtual void OnComplited() { var complite = Complited; if(complite != null) complite(); }

        /// <summary>Метод генерации события сброса последовательности</summary>
        public virtual void OnReset() { var reset = Reset; if(reset != null) reset(); }

        /// <summary>Метод генерации события исключительной ситуации</summary>
        /// <param name="error">Исключительная ситуация</param>
        public virtual void OnException(Exception error) { var exception = Exception; if(exception != null) exception(error); }

        /// <summary>Инициализация нового простейшего наблюдателя</summary>
        public SimpleObserverEx() { }

        /// <summary>Инициализация нового простейшего наблюдателя</summary>
        /// <param name="observer">Объект-наблюдатель</param>
        public SimpleObserverEx(IObserverEx<T> observer)
        {
            observer.Next += OnNext;
            observer.Complited += OnComplited;
            observer.Reset += OnReset;
            observer.Exception += OnException;
        }

        /// <summary>Метод освобождения ресурсов наблюдателя</summary>
        public virtual void Dispose() { }
    }
}